import pygame
import random
import math

# 初始化 Pygame
pygame.init()

# 游戏窗口设置
WIDTH = 640
HEIGHT = 480
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Bubble Shooter Game")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
COLORS = [RED, GREEN, BLUE, YELLOW]

# 泡泡半径
BUBBLE_RADIUS = 20

# 发射器位置
LAUNCHER_X = WIDTH // 2
LAUNCHER_Y = HEIGHT - 30

# 泡泡网格
ROWS = 10
COLS = 15
grid = [[random.choice(COLORS) if i < 5 else None for i in range(COLS)] for _ in range(ROWS)]

# 当前发射的泡泡
current_bubble = random.choice(COLORS)

# 发射速度
SPEED = 5

# 角度
angle = 90

# 计算泡泡的移动方向
def get_direction(angle):
    rad = math.radians(angle)
    dx = math.cos(rad) * SPEED
    dy = -math.sin(rad) * SPEED
    return dx, dy

# 绘制泡泡网格
def draw_grid():
    for row in range(ROWS):
        for col in range(COLS):
            if grid[row][col]:
                x = col * (2 * BUBBLE_RADIUS) + BUBBLE_RADIUS
                if row % 2 == 1:
                    x += BUBBLE_RADIUS
                y = row * (2 * BUBBLE_RADIUS) + BUBBLE_RADIUS
                pygame.draw.circle(screen, grid[row][col], (x, y), BUBBLE_RADIUS)

# 绘制发射器
def draw_launcher():
    pygame.draw.circle(screen, current_bubble, (LAUNCHER_X, LAUNCHER_Y), BUBBLE_RADIUS)
    pygame.draw.line(screen, BLACK, (LAUNCHER_X, LAUNCHER_Y), (LAUNCHER_X + 50 * math.cos(math.radians(angle)),
                                                              LAUNCHER_Y - 50 * math.sin(math.radians(angle))), 3)

# 检查碰撞
def check_collision(x, y):
    for row in range(ROWS):
        for col in range(COLS):
            if grid[row][col]:
                grid_x = col * (2 * BUBBLE_RADIUS) + BUBBLE_RADIUS
                if row % 2 == 1:
                    grid_x += BUBBLE_RADIUS
                grid_y = row * (2 * BUBBLE_RADIUS) + BUBBLE_RADIUS
                distance = ((x - grid_x) ** 2 + (y - grid_y) ** 2) ** 0.5
                if distance <= 2 * BUBBLE_RADIUS:
                    return row, col
    return None

# 检查并移除相连的相同颜色泡泡
def check_and_remove_connected(row, col):
    color = grid[row][col]
    connected = []
    stack = [(row, col)]
    visited = set()

    while stack:
        r, c = stack.pop()
        if (r, c) in visited or r < 0 or r >= ROWS or c < 0 or c >= COLS or grid[r][c] != color:
            continue
        visited.add((r, c))
        connected.append((r, c))
        stack.extend([(r - 1, c), (r + 1, c), (r, c - 1), (r, c + 1)])

    if len(connected) >= 3:
        for r, c in connected:
            grid[r][c] = None

# 主游戏循环
running = True
shooting = False
bubble_x = LAUNCHER_X
bubble_y = LAUNCHER_Y
clock = pygame.time.Clock()

while running:
    screen.fill(WHITE)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                angle = (angle + 5) % 360
            elif event.key == pygame.K_RIGHT:
                angle = (angle - 5) % 360
            elif event.key == pygame.K_SPACE and not shooting:
                shooting = True
                bubble_x = LAUNCHER_X
                bubble_y = LAUNCHER_Y

    if shooting:
        dx, dy = get_direction(angle)
        bubble_x += dx
        bubble_y += dy

        # 边界碰撞检测
        if bubble_x - BUBBLE_RADIUS <= 0 or bubble_x + BUBBLE_RADIUS >= WIDTH:
            angle = 180 - angle
        if bubble_y - BUBBLE_RADIUS <= 0:
            shooting = False
            # 找到最近的网格位置
            for row in range(ROWS):
                for col in range(COLS):
                    grid_x = col * (2 * BUBBLE_RADIUS) + BUBBLE_RADIUS
                    if row % 2 == 1:
                        grid_x += BUBBLE_RADIUS
                    grid_y = row * (2 * BUBBLE_RADIUS) + BUBBLE_RADIUS
                    distance = ((bubble_x - grid_x) ** 2 + (bubble_y - grid_y) ** 2) ** 0.5
                    if distance <= BUBBLE_RADIUS:
                        grid[row][col] = current_bubble
                        check_and_remove_connected(row, col)
                        current_bubble = random.choice(COLORS)
                        break
                else:
                    continue
                break

        collision = check_collision(bubble_x, bubble_y)
        if collision:
            shooting = False
            row, col = collision
            grid[row][col] = current_bubble
            check_and_remove_connected(row, col)
            current_bubble = random.choice(COLORS)

        pygame.draw.circle(screen, current_bubble, (int(bubble_x), int(bubble_y)), BUBBLE_RADIUS)

    draw_grid()
    draw_launcher()

    pygame.display.flip()
    clock.tick(60)

pygame.quit()